"""
Test module to verify the functionality of all built-in templates.
"""

from typing import Callable

import pytest

from cobbler.api import CobblerAPI
from cobbler.autoinstall.manager import AutoInstallationManager
from cobbler.items.distro import Distro
from cobbler.items.profile import Profile


def test_built_in_sample_old_seed(
    cobbler_api: CobblerAPI,
    autoinstall_manager: AutoInstallationManager,
    create_distro: Callable[[], Distro],
    create_profile: Callable[[str], Profile],
):
    """
    Test to verify the built-in sample old seed template.
    """
    # Arrange
    expected_result = [
        "#platform=x86, AMD64, or Intel EM64T",
        "# System authorization information",
        "",
        "# System bootloader configuration",
        "d-i    grub-installer/only_debian    boolean    true",
        "#grub-installer    grub-installer/bootdev    string    hd0",
        "d-i    grub-installer/bootdev    string    hd0",
        "d-i    debian-installer/add-kernel-opts    string ",
        "",
        "# Partition clearing information",
        "d-i partman-auto/disk string /dev/sda",
        "d-i partman-auto/method string lvm",
        "d-i partman-auto/purge_lvm_from_device boolean true",
        "d-i partman-lvm/device_remove_lvm boolean true",
        "d-i partman-lvm/confirm boolean true",
        "",
        "#d-i partman-auto/init_automatically_partition \\\\",
        "#       select Guided - use entire disk and set up LVM",
        "",
        "#d-i partman-auto/expert_recipe_file string /recipe",
        "d-i partman-auto/choose_recipe select atomic",
        "",
        "d-i partman/confirm_write_new_label boolean true",
        "d-i partman/choose_partition select finish",
        "d-i partman/confirm boolean true",
        "",
        "",
        "# Use text mode install",
        "",
        "# Firewall configuration",
        "",
        "# Run the Setup Agent on first boot",
        "",
        "# System keyboard",
        "d-i    console-setup/dont_ask_layout    note",
        "d-i    console-keymaps-at/keymap        select    us",
        "# System language",
        "",
        "# Use network installation",
        "# NOTE : The suite seems to be hardcoded on installer",
        "d-i    mirror/suite            string    $suite",
        "d-i    mirror/country          string    enter information manually",
        "d-i    mirror/http/hostname    string    $hostname",
        "d-i    mirror/http/directory   string    $directory",
        "d-i    mirror/http/proxy       string",
        "# If any cobbler repo definitions were referenced in the automated installation file profile, include them here.",
        "#apt-setup-udeb    apt-setup/services-select multiselect    security",
        "d-i    apt-setup/services-select  multiselect   security",
        "d-i    apt-setup/security_host    string        $hostname$directory-security",
        "d-i    apt-setup/volatile_host    string        $hostname$directory-volatile",
        "",
        "# Network information",
        "# NOTE : this questions are asked before downloading preseed",
        "#d-i    netcfg/get_hostname    string unassigned-hostname",
        "#d-i    netcfg/get_domain      string unassigned-hostname",
        "",
        "# Reboot after installation",
        "finish-install    finish-install/reboot_in_progress    note",
        "",
        "#Root password",
        "d-i     passwd/root-password-crypted    password    $1$mF86/UHC$WvcIcX2t6crBz2onWxyac.",
        "user-setup-udeb    passwd/root-login    boolean    true",
        "user-setup-udeb    passwd/make-user     boolean    false",
        "# SELinux configuration",
        "",
        "# Do not configure the X Window System",
        "",
        "# System timezone",
        "clock-setup    clock-setup/utc    boolean    false",
        "tzsetup-udeb    time/zone    select    America/New_York",
        "# Install OS instead of upgrade",
        "",
        "# Clear the Master Boot Record",
        "",
        "",
        "# Select individual packages and groups for install",
        "d-i    pkgsel/include    string    openssh-server",
        "tasksel    tasksel/first    multiselect    standard, desktop",
        "",
        "# Disable automatic updates",
        "d-i pkgsel/update-policy select none",
        "",
        "# Debian specific configuration",
        "# See http://www.debian.org/releases/stable/i386/apbs04.html.en & preseed documentation",
        "",
        "# By default the installer requires that repositories be authenticated",
        "# using a known gpg key. This setting can be used to disable that",
        "# authentication. Warning: Insecure, not recommended.",
        "d-i    debian-installer/allow_unauthenticated    string    true",
        "",
        "# Some versions of the installer can report back on what software you have",
        "# installed, and what software you use. The default is not to report back,",
        "# but sending reports helps the project determine what software is most",
        "# popular and include it on CDs.",
        "popularity-contest    popularity-contest/participate    boolean    false",
        "",
    ]
    target_template = cobbler_api.find_template(
        False, False, name="built-in-sample_old.seed"
    )
    if target_template is None or isinstance(target_template, list):
        pytest.fail("Could not find built-in template!")
    test_distro = create_distro()
    test_profile = create_profile(test_distro.uid)
    test_profile.autoinstall = target_template

    # Act
    result = autoinstall_manager.generate_autoinstall(test_profile, target_template)

    # Assert
    assert result == "\n".join(expected_result)


def test_built_in_sample_seed(
    cobbler_api: CobblerAPI,
    autoinstall_manager: AutoInstallationManager,
    create_distro: Callable[[], Distro],
    create_profile: Callable[[str], Profile],
):
    """
    Test to verify the built-in sample seed template.
    """
    # Arrange
    expected_result = [
        "# Mostly based on the Ubuntu installation guide",
        "# https://help.ubuntu.com/18.04/installation-guide/",
        "# Debian sample",
        "# https://www.debian.org/releases/stable/example-preseed.txt",
        "",
        "# Preseeding only locale sets language, country and locale.",
        "d-i debian-installer/locale string en_US",
        "",
        "# Keyboard selection.",
        "# Disable automatic (interactive) keymap detection.",
        "d-i console-setup/ask_detect boolean false",
        "d-i keyboard-configuration/xkb-keymap select us",
        "d-i keyboard-configuration/toggle select No toggling",
        "d-i keyboard-configuration/layoutcode string us",
        "d-i keyboard-configuration/variantcode string",
        "",
        "# netcfg will choose an interface that has link if possible. This makes it",
        "# skip displaying a list if there is more than one interface.",
        "d-i netcfg/choose_interface select auto",
        "d-i netcfg/get_hostname string test-built-in-sample-seed",
        "",
        "# If non-free firmware is needed for the network or other hardware, you can",
        "# configure the installer to always try to load it, without prompting. Or",
        "# change to false to disable asking.",
        "# d-i hw-detect/load_firmware boolean true",
        "",
        "# NTP/Time Setup",
        "d-i time/zone string US/Eastern",
        "d-i clock-setup/utc boolean true",
        "d-i clock-setup/ntp boolean true",
        "d-i clock-setup/ntp-server  string ntp.ubuntu.com",
        "",
        "# Setup the installation source",
        "d-i mirror/country string manual",
        "d-i mirror/http/hostname string 192.168.1.1",
        "d-i mirror/http/directory string $install_source_directory",
        "d-i mirror/http/proxy string",
        "",
        "",
        "# Suite to install.",
        "# d-i mirror/suite string precise",
        "# d-i mirror/udeb/suite string precise",
        "",
        "# Components to use for loading installer components (optional).",
        "#d-i mirror/udeb/components multiselect main, restricted",
        "",
        "# Disk Partitioning",
        "# Use LVM, and wipe out anything that already exists",
        "d-i partman/choose_partition select finish",
        "d-i partman/confirm boolean true",
        "d-i partman/confirm_nooverwrite boolean true",
        "d-i partman-auto/method string lvm",
        "d-i partman-lvm/device_remove_lvm boolean true",
        "d-i partman-lvm/confirm boolean true",
        "d-i partman-lvm/confirm_nooverwrite boolean true",
        "d-i partman-md/device_remove_md boolean true",
        "d-i partman-partitioning/confirm_write_new_label boolean true",
        "",
        "# You can choose one of the three predefined partitioning recipes:",
        "# - atomic: all files in one partition",
        "# - home:   separate /home partition",
        "# - multi:  separate /home, /usr, /var, and /tmp partitions",
        "d-i partman-auto/choose_recipe select atomic",
        "",
        "# If you just want to change the default filesystem from ext3 to something",
        "# else, you can do that without providing a full recipe.",
        "# d-i partman/default_filesystem string ext4",
        "",
        "# root account and password",
        "d-i passwd/root-login boolean true",
        r"d-i passwd/root-password-crypted password \$1\$mF86/UHC\$WvcIcX2t6crBz2onWxyac.",
        "",
        "# skip creation of a normal user account.",
        "d-i passwd/make-user boolean false",
        "",
        "# You can choose to install restricted and universe software, or to install",
        "# software from the backports repository.",
        "# d-i apt-setup/restricted boolean true",
        "# d-i apt-setup/universe boolean true",
        "# d-i apt-setup/backports boolean true",
        "",
        "# Uncomment this if you don't want to use a network mirror.",
        "# d-i apt-setup/use_mirror boolean false",
        "",
        "# Select which update services to use; define the mirrors to be used.",
        "# Values shown below are the normal defaults.",
        "# d-i apt-setup/services-select multiselect security",
        "# d-i apt-setup/security_host string security.ubuntu.com",
        "# d-i apt-setup/security_path string /ubuntu",
        "",
        "# Additional repositories, local[0-9] available",
        "",
        "",
        "# Enable deb-src lines",
        "# d-i apt-setup/local0/source boolean true",
        "",
        "# URL to the public key of the local repository; you must provide a key or",
        "# apt will complain about the unauthenticated repository and so the",
        "# sources.list line will be left commented out",
        "# d-i apt-setup/local0/key string http://local.server/key",
        "",
        "# By default the installer requires that repositories be authenticated",
        "# using a known gpg key. This setting can be used to disable that",
        "# authentication. Warning: Insecure, not recommended.",
        "# d-i debian-installer/allow_unauthenticated boolean true",
        "",
        "# Package selection",
        "# Default for minimal",
        "tasksel tasksel/first multiselect standard",
        "# Default for server",
        "# tasksel tasksel/first multiselect standard, web-server",
        "# Default for gnome-desktop",
        "# tasksel tasksel/first multiselect standard, gnome-desktop",
        "",
        "# Individual additional packages to install",
        "# wget is REQUIRED otherwise quite a few things won't work",
        "# later in the build (like late-command scripts)",
        "d-i pkgsel/include string ntp ssh wget",
        "",
        "# Debian needs this for the installer to avoid any question for grub",
        "# Please verify that it suit your needs as it may overwrite any usb stick",
        "",
        "# Use the following option to add additional boot parameters for the",
        "# installed system (if supported by the bootloader installer).",
        "# Note: options passed to the installer will be added automatically.",
        "d-i debian-installer/add-kernel-opts string ",
        "",
        "# Avoid that last message about the install being complete.",
        "d-i finish-install/reboot_in_progress note",
        "",
        "",
        "# This first command is run as early as possible, just after preseeding is read.",
        "# d-i preseed/early_command string [command]",
        "d-i preseed/early_command string wget -O- \\",
        "   http://192.168.1.1/cblr/svc/op/script/profile/test_built_in_sample_seed/?script=preseed_early_default | \\",
        "   /bin/sh -s",
        "",
        "# This command is run immediately before the partitioner starts. It may be",
        "# useful to apply dynamic partitioner preseeding that depends on the state",
        "# of the disks (which may not be visible when preseed/early_command runs).",
        "# d-i partman/early_command \\",
        '#       string debconf-set partman-auto/disk "$(list-devices disk | head -n1)"',
        "",
        "# This command is run just before the install finishes, but when there is",
        "# still a usable /target directory. You can chroot to /target and use it",
        "# directly, or use the apt-install and in-target commands to easily install",
        "# packages and run commands in the target system.",
        "# d-i preseed/late_command string [command]",
        "d-i preseed/late_command string wget -O- \\",
        "   http://192.168.1.1/cblr/svc/op/script/profile/test_built_in_sample_seed/?script=preseed_late_default | \\",
        "   chroot /target /bin/sh -s",
        "",
    ]
    target_template = cobbler_api.find_template(
        False, False, name="built-in-sample.seed"
    )
    if target_template is None or isinstance(target_template, list):
        pytest.fail("Could not find built-in template!")
    test_distro = create_distro()
    test_profile = create_profile(test_distro.uid)
    test_profile.autoinstall = target_template

    # Act
    result = autoinstall_manager.generate_autoinstall(test_profile, target_template)

    # Assert
    assert result == "\n".join(expected_result)
